#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

template <typename T = int, size_t kSize = 10>
class Stack
{
public:
    Stack()
    : _top(-1)
    , _data(new T[kSize]())
    {
        cout << "Satck()" << endl;
    }
    ~Stack();
    bool empty() const;
    bool full() const;
    void push(const T &number);
    void pop();
    T top() const;

    /* template <typename K> */
    /* virtual void print(K k); */
    template <typename K>
    void func(K k);
private:
    int _top;
    /* int *_data; */
    /* double *_data; */
    /* string *_data; */
    T *_data;
};

template <typename T, size_t kSize>
template <typename K>
/* template <typename T, size_t kSize, typename K> //error */
void Stack<T, kSize>::func(K k)
{

}

template <typename T, size_t kSize>
Stack<T, kSize>::~Stack()
{
    cout << "~Stack()" << endl;
    if(_data)
    {
        delete [] _data;
        _data = nullptr;
    }
}

template <typename T, size_t kSize>
bool Stack<T, kSize>::empty() const
{
    return -1 == _top;
}

template <typename T, size_t kSize>
bool Stack<T, kSize>::full() const
{
    return _top == kSize - 1;
}

template <typename T, size_t kSize>
void Stack<T, kSize>::push(const T &number)
{
    if(!full())
    {
        _data[++_top] = number;
    }
    else
    {
        cout << "The stack is full, not push data" << endl;
        return;
    }
}

template <typename T, size_t kSize>
void Stack<T, kSize>::pop()
{
    if(!empty())
    {
        --_top;
    }
    else
    {
        cout << "The stack is empty, not pop data" << endl;
        return;
    }
}

template <typename T, size_t kSize>
T Stack<T, kSize>::top() const
{
    return _data[_top];
}

void test()
{
    Stack<int, 20> st;
    cout << "该栈是不是空的 = " << st.empty() << endl;
    st.push(1);
    cout << "该栈是不是满的 = " << st.full() << endl;
    
    for(size_t idx = 2; idx != 22; ++idx)
    {
        st.push(idx);
    }
    cout << "该栈是不是满的 = " << st.full() << endl;

    while(!st.empty())
    {
        cout << st.top() << "  ";
        st.pop();
    }
    cout << endl;
    cout << "该栈是不是空的 = " << st.empty() << endl;
}

void test2()
{
    Stack<string> st;
    cout << "该栈是不是空的 = " << st.empty() << endl;
    st.push("aaa");
    cout << "该栈是不是满的 = " << st.full() << endl;
    
    for(size_t idx = 1; idx != 12; ++idx)
    {
        st.push(string(3, 'a' + idx));//bbb ccc ddd
    }
    cout << "该栈是不是满的 = " << st.full() << endl;

    while(!st.empty())
    {
        cout << st.top() << "  ";
        st.pop();
    }
    cout << endl;
    cout << "该栈是不是空的 = " << st.empty() << endl;
}

int main(int argc, char *argv[])
{
    test2();
    return 0;
}

